
package sk.robocup.dvanastyhrac.tactics;

import robocup.component.ControllerNumbers.PLAY_MODE;
import robocup.component.SConf;
import robocup.component.actions.TurnAction;
import robocup.component.geometry.Vektor;
import robocup.component.tactics.SearchBallState;
import robocup.component.tactics.StateEvaluation;

/**
 * Stav sa spusta pri standartnych situaciach timu a len pre hraca, ktoreho
 * ulohou je rozohrat. Hrac s loptou caka 10 cyklov, pocas ktorych zistuje
 * situaciu na ihrisku (poziciu spolu- a protihracov).
 * 
 * @author polak.marek
 */
public class WaitAndLookState12
    extends SearchBallState
{

    int waitTime;       //dlzka cakania
    int startedCycle;   //pociatocny cyklus cakania



    /**
     * Konstruktor stavu cakania. Nastavuje dlzku cakania na 10 taktov, start point
     * na aktualny takt a typ stavu
     * @param parent Evaluator ktory vyhodnocuje prinos taktik.
     */
    public WaitAndLookState12(StateEvaluation parent)
    {
        super(parent);
        waitTime = 10;
        startedCycle = this.getWorld().getCycle();
        state = STATES.PLAYER_WAIT;
    }




    /**
     * preCondition vracia false ak:
     *  - je lopta v hre: PlayMode = PLAY_ON
     *  - lopta je mimo hry, ale nekopeme ziadnu zo standart. situacii
     *  - hrac nema loptu v kickable area
     *  - cakali by sme dlhsie ako je urcena doba cakania
     *
     * @return boolean
     */
    @Override
    public boolean preCondition()
    {
        //ak je lopta v hre, vrat false
        if(this.getWorld().getPlayMode()==PLAY_MODE.PLAY_ON) return false;

        /* tiez vrat false ak bud nema hrac loptu, alebo je iny herny mod ako
         * mod Standardnyh situacii
         * FREE_KICK_OWN,INDIRECT_FREE_KICK_OWN, CORNER_KICK_OWN, 
         * GOAL_KICK_OWN, KICK_IN_OWN, KICK_OFF_OWN
         */
        if(this.getWorld().getPlayMode() != PLAY_MODE.META_STANDARD_OWN && !this.checkMyBall())
            return false;

        //cislo taktu
        int now = getWorld().getCycle();

        //ak caka menej ako
        return now < startedCycle + waitTime || now > startedCycle + waitTime;
    }




    /**
     * Hlavna akcia spociva v obzerani sa hraca po ihrisku, meneni pohladov a
     * tym v aktualizacii pozicii spolu- a protihracov. Vdaka tomu ma v
     * nasledujucich stavoch presnejsie info a robi menej chyb pri rozhodovani.
     * Akcia vola rodicovsku 'main action' z triedy SearchBallState.
     */
    @Override
    public void calculateMainAction()
    {
        //debug>  System.out.println("player: "+getPlayer().getNumber()+" = WAIT STATE: Start cycle="+startedCycle+" cycle now="+getWorld().getCycle());

        //aktualizuj cas pociatocneho cyklu, ake je neaktualny
        int now = getWorld().getCycle();
        if(now > startedCycle + waitTime)
            startedCycle = now;


        //pocitam hlavnu akciu SearchBall state-u
       if(!turnedToField())
       {

          // vypocitam uhol o ktory sa mam otocit - DAInamite sposob
          double angleToField = Vektor.normalize(SConf.getInstance().GOAL_POS_OTHER.sub(
                  this.getWorld().getMyNextPosition()).getAngle() - this.getWorld().getBodyAngle());


          double turnAngle;
          turnAngle = this.getWorld().getSelfRef().getAngleForTurn(angleToField);

          // otocim sa
          mainAction = new TurnAction(turnAngle);
       }else
            super.calculateMainAction();
    }






    /**
     * stav sa vykona vzdy so 100% pravdebodobnostou uspechu (mame loptu a
     * cakame, tam sa neda vela pokazit)
     * @return
     */
    @Override
    protected double successProbability()
    {
        return 1.0D;
    }





    /**
     * benefit je najvacsi mozny (1.0), ziskavame prehlad o poziciach hracov
     * @return
     */
    @Override
    protected double successBenefit()
    {
        return 1.0D;
    }


    /**
     * funkcia zistuje, ci je hrac otoceny smerom do pola,alebo nie. Ak nie,
     * vrati false.
     * @return
     */
    private boolean turnedToField()
    {
        boolean retVal = false;

        double playerBodyAngle = this.getWorld().getSelfRef().getBodyDir();
        double playerHeadAngle = this.getWorld().getSelfRef().getHeadDir();

        //body angle
        if(playerBodyAngle > 135.0 || playerBodyAngle < -135.0)
        {
            retVal = true;
            //debug> System.out.println("body angle je prilis velky: "+playerBodyAngle);
        }

        // brat do uvahy aj head-agle?
        if(playerHeadAngle >135.0 || playerHeadAngle < -135.0)
        {
            retVal = true;
            //debug> System.out.println("head angle je prilis velky: "+playerHeadAngle);
        }

        return retVal;
    }

}
